<?php 

/***********************************************************
 * 
 * RokkoMVC for WordPress
 * Copyright (c) 2012 Rodrigo Silveira
 * http://www.rodrigo-silveira.com
 * http://code.google.com/p/rokko-mvc-for-wordpress/
 * 
 ***********************************************************/


/***********************************************************
 * The bootstrap class. Its purpose is to inspect an HTTP
 * request and determine if the request is for asynchronous
 * content. If so, it loads the requested action and returns
 * its content.
 ***********************************************************/
namespace rokko {
    class RokkoMVC {

        /***********************************************************
        * Async requests identified by the presence of POST parameter
        * reqTypeAsync = true
        ***********************************************************/
        public static function isAsyncRequest($pReq) {
            return key_exists("reqTypeAsync", $pReq);
        }


        /***********************************************************
        * Attempt to fetch the requested action. If a function
        * exits in your main controller with the same name as the
        * requested action, then that function is invoked.
        ***********************************************************/
        public static function fetchAsync($pAction, RokkoController $pController) {
            if (method_exists($pController, $pAction)) {
                $pController->$pAction();
            }

            else {
                throw new RokkoAsyncReqException("Invalid async request name");
            }
        }


        /***********************************************************
        * For an async request to work, two parameters must be found
        * with the request:
        *    - isAsyncRequest = indicates that the request is for RokkoMVC to handle
        *    - reqName = the name of the action to be invoked, and its corresponding controller, in the form of myAction@myController
        *    
        * If the first parameter is not found, then RokkoMVC will ignore the request.
        * If the second parameter is missing, but the first one is found, the request will return an exception.
        ***********************************************************/
        public static function bootstrap($pReq, $pWpdb) {
            if (RokkoMVC::isAsyncRequest($pReq)) {

                $req = explode("@", @$pReq["reqName"]);
                $controller = $req[1]."Controller";

                //
                // Load ma dependencies
                // TODO: Load these dependencies dynamically
                //
                require_once "rokkomvc/controllers/RokkoController.php";
                require_once "rokkomvc/models/RokkoModel.php";

                require_once "rokkomvc/controllers/tables_controller.php";
                require_once "rokkomvc/models/table.php";

                try {
                    RokkoMVC::fetchAsync($req[0], new $controller($pWpdb));
                } catch (RokkoAsyncReqException $e) {
                    RokkoMVC::setContentType(RokkoMIME::JSON);
                    echo json_encode(array("error" => $e->toArray()));
                }

                exit;
            }
        }

        public static function setContentType($pType) {
            switch ($pType) {
                case RokkoMIME::HTML:
                    header("Content-type: text/html");
                    break;

                case RokkoMIME::JS:
                    header("Content-type: application/x-javascript");
                    break;

                case RokkoMIME::JSON:
                    header("Content-type: application/json");
                    break;

                case RokkoMIME::CSS:
                    header("Content-type: text/css");
                    break;

                default:
                    header("Content-type: text/html");
            }
        }
    }


    /***********************************************************
    * A poor man's PHP enumerations. These are used so speed
    * up value lookups in a switch statement or the like. Better
    * performance using these than comparing strings all the time. 
    ***********************************************************/
    class RokkoMIME {
        const HTML = 0;
        const JS = 1;
        const JSON = 2;
        const CSS = 3;
    }
}
